package com.xy.lang.util;

import java.util.Objects;
import java.util.function.Predicate;
import java.util.function.Supplier;

public class OpUtils {

    public static <R> R tryGet(Supplier<R> supplier, long timeoutMillis) {
        return tryGet(supplier, null, timeoutMillis);
    }

    public static <R> R tryGet(Supplier<R> supplier, Predicate<R> predicate, long timeoutMillis) {
        return tryGet(supplier, predicate, timeoutMillis, 1L);
    }

    public static <R> R tryGet(Supplier<R> supplier, Predicate<R> predicate, long timeoutMillis, long intervalMillis) {
        Objects.requireNonNull(supplier, "The supplier is required.");
        if(timeoutMillis < 1L) {
            return supplier.get();
        }
        if(intervalMillis < 1L) {
            intervalMillis = 1L;
        }
        long delta, base = System.currentTimeMillis();
        R result;
        for(;;) {
            result = supplier.get();
            if(predicate != null) {
                if (predicate.test(result)) {
                    return result;
                }
            } else {
                if(null != result) {
                    return result;
                }
            }
            delta = (System.currentTimeMillis() - base);
            if(delta > timeoutMillis) {
                return null;
            }
            if(intervalMillis > 0) {
                long s = intervalMillis > delta ? delta : intervalMillis;
                try {
                    Thread.sleep(s);
                } catch (InterruptedException e) {
                    //do nothing
                }
            }
        }
    }

}
